package com.lkdont.android.media.audio.recorder

import android.media.AudioRecord
import com.lkdont.android.media.recorder.BaseRecorder
import com.lkdont.android.media.recorder.RecordState
import com.lkdont.android.media.recorder.Recorder

/**
 * PCM原始音频数据录制器
 *
 * @author lqd
 */
class PcmRecorder : BaseRecorder() {

    companion object {
        private const val TAG = "PcmRecorder"
    }

    private var audioSource: Int = 0
    private var audioSampleRate: Int = 0
    private var audioChannelConfig: Int = 0
    private var audioFormat: Int = 0

    /*** 设置参数 */
    fun setConfig(source: Int, sampleRate: Int, channelConfig: Int, format: Int) {
        checkState(RecordState.INITIALIZED, "当前状态($state)不能调用setConfig方法")
        audioSource = source
        audioSampleRate = sampleRate
        audioChannelConfig = channelConfig
        audioFormat = format
        changeState(RecordState.INITIALIZED)
    }

    private var recorder: AudioRecord? = null
    var bufferSize: Int = 0
        private set

    override fun prepareRecorder() {
        if (recorder != null) {
            recorder!!.release()
        }
        // 计算每帧音频数据大小
        bufferSize = AudioRecord.getMinBufferSize(audioSampleRate, audioChannelConfig, audioFormat)
        // 初始化AudioRecord
        recorder =
            AudioRecord(audioSource, audioSampleRate, audioChannelConfig, audioFormat, bufferSize)
    }

    override fun startRecorder() {
        recorder!!.startRecording()
    }

    override fun changeState(newState: RecordState) {
        super.changeState(newState)
        if (newState == RecordState.RECORDING) {
            // 启动录制线程
            Thread(RecordAudioTask()).start()
        }
    }

    override fun stopRecorder() {
        recorder!!.stop()
        recorder = null
    }

    override fun pauseRecorder() {
    }

    override fun resumeRecorder() {
    }

    override fun resetRecorder() {
        releaseRecorder()
    }

    override fun releaseRecorder() {
        recorder?.release()
        recorder = null
        bufferSize = 0
        audioSource = 0
        audioSampleRate = 0
        audioChannelConfig = 0
        audioFormat = 0
    }

    //******************************** 录制任务 ********************************//

    /*** 录制数据回调 */
    var onAudioDataAvailable: ((recorder: Recorder, data: ByteArray, length: Int) -> Unit)? = null

    private inner class RecordAudioTask : Runnable {
        override fun run() {
            // 设置线程优先权重
            android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO)
            val audioBuffer = ByteArray(bufferSize)
            var readLength: Int
            while (isRecording && recorder != null) {
                try {
                    // 读取录制音频数据
                    readLength = recorder!!.read(audioBuffer, 0, audioBuffer.size)
                    if (!isPausing && readLength > 0) {
                        // 只有在非暂停状态下才输出数据
                        onAudioDataAvailable?.invoke(this@PcmRecorder, audioBuffer, readLength)
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }
    }
}